import Control.Monad.Writer
import Data.Char
import Data.Functor.Identity

left', right' :: Int -> Writer String Int
left' x = writer (x - 1, "move left\n")
right' x = writer (x + 1, "move right\n")

-- ------------ 演示 pass 的用法
-- Writer String 才是 Monad, 
-- class (Monoid w, Monad m) => MonadWriter w m | m -> w where
--   writer :: (a, w) -> m a 
-- 例如 writer(Int, String) -> Writer String Int, 即 m is (Writer String)

foo2 :: (MonadWriter String m, Num a) => a -> m (a, String -> String)
foo2 x = writer ((x - 1, map toUpper), "foo")

move2 :: (Num b) => Int -> WriterT String Identity b
move2 i = do
  x <- left' i
  pass (foo2 10)

foo2b :: Writer String (Int, String -> String)
foo2b = writer ((99, map toUpper), "bar")

move2b i = do
  x <- left' i
  pass foo2b